"""
权限管理模块
实现基于角色的访问控制（RBAC）
"""
from functools import wraps
from rest_framework import permissions
from rest_framework.exceptions import PermissionDenied
from django.contrib.auth.models import Group
from .models import Role


class RolePermissionService:
    """角色权限服务"""
    
    @staticmethod
    def get_user_permissions(user):
        """
        获取用户的所有权限
        通过用户所属的用户组，找到关联的角色，汇总所有权限
        """
        if not user or not user.is_authenticated:
            return set()
        
        # 超级管理员拥有所有权限
        if user.is_superuser:
            return {'*'}  # 通配符表示所有权限
        
        # 获取用户所属的所有用户组
        user_groups = user.groups.all()
        
        # 获取这些用户组关联的所有角色
        roles = Role.objects.filter(user_groups__in=user_groups).distinct()
        
        # 汇总所有权限
        permissions = set()
        for role in roles:
            if role.permissions:
                permissions.update(role.permissions)
        
        return permissions
    
    @staticmethod
    def has_permission(user, permission_code):
        """
        检查用户是否拥有指定权限
        
        Args:
            user: Django User对象
            permission_code: 权限代码，如 'host.view', 'host.add' 等
        
        Returns:
            bool: True表示有权限，False表示无权限
        """
        user_permissions = RolePermissionService.get_user_permissions(user)
        
        # 超级管理员拥有所有权限
        if '*' in user_permissions:
            return True
        
        # 检查是否有具体权限
        return permission_code in user_permissions
    
    @staticmethod
    def has_any_permission(user, permission_codes):
        """
        检查用户是否拥有任一指定权限
        
        Args:
            user: Django User对象
            permission_codes: 权限代码列表
        
        Returns:
            bool: True表示有任一权限，False表示无任何权限
        """
        user_permissions = RolePermissionService.get_user_permissions(user)
        
        # 超级管理员拥有所有权限
        if '*' in user_permissions:
            return True
        
        # 检查是否有任一权限
        return any(code in user_permissions for code in permission_codes)
    
    @staticmethod
    def has_all_permissions(user, permission_codes):
        """
        检查用户是否拥有所有指定权限
        
        Args:
            user: Django User对象
            permission_codes: 权限代码列表
        
        Returns:
            bool: True表示有所有权限，False表示缺少某些权限
        """
        user_permissions = RolePermissionService.get_user_permissions(user)
        
        # 超级管理员拥有所有权限
        if '*' in user_permissions:
            return True
        
        # 检查是否有所有权限
        return all(code in user_permissions for code in permission_codes)


class HasPermission(permissions.BasePermission):
    """
    DRF权限类：检查用户是否拥有指定权限
    
    使用方法：
        class MyViewSet(viewsets.ModelViewSet):
            permission_classes = [HasPermission]
            required_permission = 'host.view'
    """
    
    def has_permission(self, request, view):
        # 如果视图没有指定required_permission，则默认允许
        if not hasattr(view, 'required_permission'):
            return True
        
        required_permission = view.required_permission
        
        # 如果是字典形式，根据HTTP方法获取权限
        if isinstance(required_permission, dict):
            method = request.method.lower()
            required_permission = required_permission.get(method, None)
            if required_permission is None:
                return True
        
        # 检查权限
        return RolePermissionService.has_permission(request.user, required_permission)
    
    def has_object_permission(self, request, view, obj):
        # 对象级别权限检查
        return self.has_permission(request, view)


def require_permission(permission_code):
    """
    函数装饰器：要求用户拥有指定权限
    
    使用方法：
        @require_permission('host.add')
        def my_view(request):
            pass
    """
    def decorator(func):
        @wraps(func)
        def wrapper(request, *args, **kwargs):
            if not RolePermissionService.has_permission(request.user, permission_code):
                raise PermissionDenied(f'您没有权限执行此操作（需要权限: {permission_code}）')
            return func(request, *args, **kwargs)
        return wrapper
    return decorator


def require_any_permission(*permission_codes):
    """
    函数装饰器：要求用户拥有任一指定权限
    
    使用方法：
        @require_any_permission('host.view', 'host.add')
        def my_view(request):
            pass
    """
    def decorator(func):
        @wraps(func)
        def wrapper(request, *args, **kwargs):
            if not RolePermissionService.has_any_permission(request.user, permission_codes):
                raise PermissionDenied(f'您没有权限执行此操作（需要权限: {" 或 ".join(permission_codes)}）')
            return func(request, *args, **kwargs)
        return wrapper
    return decorator


def require_all_permissions(*permission_codes):
    """
    函数装饰器：要求用户拥有所有指定权限
    
    使用方法：
        @require_all_permissions('host.view', 'host.add')
        def my_view(request):
            pass
    """
    def decorator(func):
        @wraps(func)
        def wrapper(request, *args, **kwargs):
            if not RolePermissionService.has_all_permissions(request.user, permission_codes):
                raise PermissionDenied(f'您没有权限执行此操作（需要权限: {" 和 ".join(permission_codes)}）')
            return func(request, *args, **kwargs)
        return wrapper
    return decorator
